﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MySql.Data.MySqlClient;
using System.Data;
using l1cs.server.model.Instance;
using l1cs.server.utils;
using l1cs.server.datatables;

namespace l1cs.server.model
{
    public class Getback
    {
        private static Logger _log = Logger.getLogger( typeof( Getback ).FullName );

        private static Random _random = new Random();

        private static Dictionary<int, List<Getback>> _getback = new Dictionary<int, List<Getback>>();

        private int _areaX1;
        private int _areaY1;
        private int _areaX2;
        private int _areaY2;
        private int _areaMapId;
        private int _getbackX1;
        private int _getbackY1;
        private int _getbackX2;
        private int _getbackY2;
        private int _getbackX3;
        private int _getbackY3;
        private int _getbackMapId;
        private int _getbackTownId;
        private int _getbackTownIdForElf;
        private int _getbackTownIdForDarkelf;
        private bool _escapable; // 未使用(mapidsに持っているし、ここに来る前にチェックされている)

        private Getback() { }

        private bool isSpecifyArea()
        {
            return ( _areaX1 != 0 && _areaY1 != 0 && _areaX2 != 0 && _areaY2 != 0 );
        }

        public static void loadGetBack()
        {
            _getback.Clear();
            String sqlstr = "SELECT * FROM getback ORDER BY area_mapid,area_x1 DESC";
            using ( MySqlWrapper wrapper = new MySqlWrapper() )
            {
                foreach ( DataRow item in wrapper.GetDataTable( sqlstr ).Rows )
                {
                    Getback getback = new Getback();
                    getback._areaX1 = SqlUtils.toInt( item["area_x1"] );
                    getback._areaY1 = SqlUtils.toInt( item["area_y1"] );
                    getback._areaX2 = SqlUtils.toInt( item["area_x2"] );
                    getback._areaY2 = SqlUtils.toInt( item["area_y2"] );
                    getback._areaMapId = SqlUtils.toInt( item["area_mapid"] );
                    getback._getbackX1 = SqlUtils.toInt( item["getback_x1"] );
                    getback._getbackY1 = SqlUtils.toInt( item["getback_y1"] );
                    getback._getbackX2 = SqlUtils.toInt( item["getback_x2"] );
                    getback._getbackY2 = SqlUtils.toInt( item["getback_y2"] );
                    getback._getbackX3 = SqlUtils.toInt( item["getback_x3"] );
                    getback._getbackY3 = SqlUtils.toInt( item["getback_y3"] );
                    getback._getbackMapId = SqlUtils.toInt( item["getback_mapid"] );
                    getback._getbackTownId = SqlUtils.toInt( item["getback_townid"] );
                    getback._getbackTownIdForElf = SqlUtils.toInt( item["getback_townid_elf"] );
                    getback._getbackTownIdForDarkelf = SqlUtils.toInt( item["getback_townid_darkelf"] );
                    getback._escapable = Convert.ToBoolean( item["scrollescape"] );
                    List<Getback> getbackList;
                    _getback.TryGetValue( getback._areaMapId, out getbackList );
                    if ( getbackList == null )
                    {
                        getbackList = new List<Getback>();
                        _getback[getback._areaMapId] = getbackList;
                    }
                    getbackList.Add( getback );
                }
            }
        }

        /**
         * pcの現在地から帰還ポイントを取得する。
         * 
         * @param pc
         * @param bScroll_Escape(未使用)
         * @return locx,locy,mapidの順に格納されている配列
         */
        public static int[] GetBack_Location( L1PcInstance pc, bool bScroll_Escape )
        {

            int[] loc = new int[3];

            int nPosition = _random.Next( 3 );

            int pcLocX = pc.getX();
            int pcLocY = pc.getY();
            int pcMapId = pc.getMapId();
            List<Getback> getbackList = _getback[pcMapId];

            if ( getbackList != null )
            {
                Getback getback = null;
                foreach ( Getback gb in getbackList )
                {
                    if ( gb.isSpecifyArea() )
                    {
                        if ( gb._areaX1 <= pcLocX && pcLocX <= gb._areaX2
                                && gb._areaY1 <= pcLocY && pcLocY <= gb._areaY2 )
                        {
                            getback = gb;
                            break;
                        }
                    }
                    else
                    {
                        getback = gb;
                        break;
                    }
                }

                loc = ReadGetbackInfo( getback, nPosition );

                // town_idが指定されている場合はそこへ帰還させる
                if ( pc.isElf() && getback._getbackTownIdForElf > 0 )
                {
                    loc = L1TownLocation
                            .getGetBackLoc( getback._getbackTownIdForElf );
                }
                else if ( pc.isDarkelf() && getback._getbackTownIdForDarkelf > 0 )
                {
                    loc = L1TownLocation
                            .getGetBackLoc( getback._getbackTownIdForDarkelf );
                }
                else if ( getback._getbackTownId > 0 )
                {
                    loc = L1TownLocation.getGetBackLoc( getback._getbackTownId );
                }
            }
            // getbackテーブルにデータがない場合、SKTに帰還
            else
            {
                loc[0] = 33089;
                loc[1] = 33397;
                loc[2] = 4;
            }
            return loc;
        }

        private static int[] ReadGetbackInfo( Getback getback, int nPosition )
        {
            int[] loc = new int[3];
            switch ( nPosition )
            {
                case 0:
                    loc[0] = getback._getbackX1;
                    loc[1] = getback._getbackY1;
                    break;

                case 1:
                    loc[0] = getback._getbackX2;
                    loc[1] = getback._getbackY2;
                    break;

                case 2:
                    loc[0] = getback._getbackX3;
                    loc[1] = getback._getbackY3;
                    break;
            }
            loc[2] = getback._getbackMapId;

            return loc;
        }
    }

}